#ifndef __MarbleMax_h__
#define __MarbleMax_h__

/* 

Marble Max

Trevor Debrecht
Mason Heller
Joey Haun

*/

#include <Ogre.h>
#include <OIS/OIS.h>
#include <CEGUI/CEGUISystem.h>
#include <CEGUI/CEGUISchemeManager.h>
#include <OgreCEGUIRenderer.h>
#include <string.h>
#include <OgreNewt.h>
using namespace std;
using namespace Ogre;

#include "Object.h"
#include "marble.h"
//#include "ObjectFileManager.h"
//#include "ObjectFileSerializer.h"

// enums

enum Game_State								// current game state
{
	BUILDSTATE,								// building the track
	ROLLSTATE,								// the marble is rolling on the track
	MENUSTATE								// out of game
};

enum Build_Mode
{
	BM_BUILD,								// adding pieces to the track
	BM_BULLDOZE								// deleting pieces from the world
};

enum Menu_State
{
	MAINMENU,								// includes main
	EXITMENU,								// exit (y/n)
	OPTIONMENU,								// options
	PAUSEMENU,								// pause (of course)
	PLAYMENU,								// menu to select level and ship, etc before play
	BUILDGUI								// gui items to put on screen during race
};

enum Track_Piece
{
	DOUBLE,									// different types of track pieces
	SINGLE,
	HALF,
	NORMAL,
	SHARP
};

class Marble_Max : public FrameListener, public OIS::MouseListener, public OIS::KeyListener
{
public:
	Marble_Max();
	virtual ~Marble_Max();

	virtual void go();

protected:
// functions
	// start program
	virtual bool initOgreCore();			// start ogre
	virtual bool initialise();				// start render systems
	virtual bool initGame();				// start game

	// create listeners
	virtual bool createFrameListener();		// create the frame listener
	virtual bool createResourceListener();	// create the resource listener
	virtual bool createInputListener(Ogre::RenderWindow *renderWindow);		// create the input listener

	// create visuals
	virtual bool createCamera();			// create the camera
	virtual bool createViewports();			// create the viewing window
	virtual bool createGUI();

	// Create scene
	virtual bool createScene();				// create the scene
	virtual bool createSceneManager();		// create the scene manager

	virtual bool createMarbleScene();		// create the outside world
	//virtual bool createMenuScene();			// create the menu screen

	//virtual bool createGUI();				// create the Graphical User Interface
	//virtual bool createMenu();				// create the main menus
	//virtual bool createHUD();				// create the Heads Up Display (quickbars)

	// start resources
	virtual void addResourceLocations();	// add resources
	virtual void initResources();			// initialise resources

	// Kill scene
	virtual void destroyScene();			// kill scene and everything in it

	// Kill listeners
	virtual void killInputListener();		// kill the input listener

	// OIS overrides
	virtual bool mousePressed(const OIS::MouseEvent &mevt, OIS::MouseButtonID button);	// if mouse is clicked
	virtual bool mouseReleased(const OIS::MouseEvent &mevt, OIS::MouseButtonID button);	// if mouse is released
	virtual bool mouseMoved(const OIS::MouseEvent &mevt);								// if mouse is moved

	virtual bool keyPressed(const OIS::KeyEvent &kevt);		// if a keyboard key is pressed
	virtual bool keyReleased(const OIS::KeyEvent &kevt);	// if a keyboard key is released

	// in game functions
	virtual bool frameStarted(const FrameEvent& evt);	// the frame started
	virtual bool frameEnded(const FrameEvent& evt);		// the frame ended
	virtual bool rollState(const FrameEvent& evt);		// the marble is rolling on the track
	virtual bool buildState(const FrameEvent& evt);		// building the track
		virtual bool bsBuild(const FrameEvent& evt);	// adding pieces to the track
		virtual bool bsBulldoze(const FrameEvent& evt);	// deleting pieces from the world
		virtual Ogre::Vector2 buildQuery();
		virtual Ogre::String bulldozeQuery();
		virtual bool placeObject();
		virtual bool removeObject();
		virtual bool checkForSpace();		// check where the user clicked to see if that location is open or not (cycle through vector)
		virtual int getSpace();
		virtual bool updateMouseObject();
		virtual bool startRoll();
			virtual bool createBall();
		virtual bool buildTrack();
			virtual bool increaseSlope();
			virtual bool decreaseSlope();
		virtual bool createTrackPieces();
		//virtual bool createObject(Ogre::String name, Ogre::String filename, Ogre::Vector3 pos);
	virtual bool menuState(const FrameEvent& evt);		// menu not during gameplay
	virtual bool switchState(Game_State);				// switch game state between menu, roll, and build

	// movement functions
	virtual void moveCamera();				// move the camera

// variables

	// visual
	SceneManager* mSceneMgr;	// scene manager
	RenderWindow* mWindow;	// game's window
	Viewport* mainView;		// window's viewport
	CEGUI::Renderer *mGUIRenderer;
	CEGUI::System *mGUISystem;

	Camera* mCamera;	// camera
	Camera* menuCam;	// camera for menu
	SceneNode* camNode;	// the camera's node
	SceneNode* camYawNode;	// the camera's yaw node
	SceneNode* camPitchNode;	// the camera's pitch node
	SceneNode* tempNode;
	SceneNode* mouseNode;
	Entity* tempEntity;
	Entity* mouseEntity;

	Vector2 mouseLoc;		// location of mouse on the 2-d plane of the world
	int objectHeight;		// height of the object to be built

	Ogre::RaySceneQuery* mRaySceneQuery;

	// Physics (Newton)
	OgreNewt::World *mWorld;
	OgreNewt::BasicFrameListener *mOgreNewtListener;

	// movement
	Ogre::Real mMoveScale;
	Ogre::Real mMoveSpeed;
	Ogre::Real mRotScale;
	Ogre::Real mRotSpeed;

	Ogre::Vector3 mMoveVector;
	Ogre::Vector3 mTranslateVector;

	Ogre::Radian mRotX;
	Ogre::Radian mRotY;
	
	bool mRightMDown;			// if the right mouse button is down
	bool mRightMUp;
	bool mLeftMDown;
	bool mLeftMUp;

	// Debug stuffs
	Overlay* mDebugOverlay;					// Ogre overlay (debug purposes only)
	Ogre::String mDebugString;				// debug string
	OverlayElement* statCFPS;				// current frames per second
	OverlayElement* statAFPS;				// average frames per second
	OverlayElement* statDbg;				// debug text
	OverlayElement* statLoc;				// current player location
	OverlayElement* statSpeed;				// current player speed
	OverlayElement* statAccel;				// current player acceleration

	// User input
	OIS::InputManager* mInputMgr;			// manages all input
	OIS::Mouse*    mMouse;					// manages mouse
	OIS::Keyboard* mKeyboard;				// manages keyboard

	// Game states
	Game_State currGameState;				// the current state of play
	Build_Mode currBuildMode;				// the current mode of building
	Menu_State currMenuState;				// the currently displayed menu
	Menu_State lastMenuState;				// the last displayed menu, for purposes of going 'back' in the menu efficiently

	//Game objects
	vector <Object> Objects;
	int numObjects;
	int numBalls;
	Track_Piece mCurrTrack;
	bool space[150][20][150];

	Marble *mBall;
};

#endif